package com.pengpeng.rabbitmq.register;

import com.pengpeng.rabbitmq.bean.MqExchange;
import com.pengpeng.rabbitmq.bean.MqQueue;
import com.pengpeng.rabbitmq.declare.AmBindDeclare;
import com.pengpeng.rabbitmq.declare.AmQueueDeclare;
import com.pengpeng.rabbitmq.listen.AbstractMessageHandler;
import com.pengpeng.rabbitmq.listen.MessageListen;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.amqp.core.Binding;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.Map;

/**
 * @author 彭鹏
 * @date 2021/10/19.
 */
@Data
public abstract class AbstractRegisterQueue {

    public final Log logger = LogFactory.getLog(this.getClass());
    @Autowired
    AmBindDeclare amBindDeclare;
    @Autowired
    AmQueueDeclare amQueueDeclare;
    @Autowired
    MessageListen messageListen;

    @Value("${spring.rabbitmq.queue.isAck:false}")
    private Boolean isAck;

    /**
     * 子类提供自定义的消息监听
     *
     * @return
     */
    public abstract AbstractMessageHandler messageHandler();

    /**
     * 实例化队列名
     *
     * @param queue
     * @return
     */
    public AbstractRegisterQueue queue(String queue) {
        this.queue = queue;
        return this;
    }

    /**
     * 实例化交换机
     *
     * @param exchange
     * @return
     */
    public AbstractRegisterQueue exchange(String exchange) {
        this.exchange = exchange;
        return this;
    }

    /**
     * 实例化路由键
     *
     * @param routingKey
     * @return
     */
    public AbstractRegisterQueue routingKey(String routingKey) {
        this.routingKey = routingKey;
        return this;
    }

    /**
     * 实例化结构化属性
     *
     * @param properties
     * @return
     */
    public AbstractRegisterQueue properties(Map<String, Object> properties) {
        this.properties = properties;
        return this;
    }

    /**
     * 队列名
     */
    private String queue;
    /**
     * 交换机 默认是 amq.direct 交换机
     */
    private String exchange = MqExchange.DEFAULT_DIRECT_EXCHANGE;
    /**
     * 路由键 默认是队列名
     */
    private String routingKey = this.getQueue();
    /**
     * 结构化属性
     */
    private Map<String, Object> properties;

    public String getRoutingKey() {
        if (StringUtils.isEmpty(this.routingKey)) {
            return this.getQueue();
        }
        return this.routingKey;
    }

    /**
     * 注册队列，并且监听队列
     *
     * @return
     */
    public boolean registerQueue() {
        MqQueue mqQueue = new MqQueue().name(this.queue);
        this.amQueueDeclare.declareQueue(mqQueue);
        boolean tag = this.amBindDeclare.bind(this.queue, Binding.DestinationType.QUEUE, this.exchange, this.getRoutingKey(), this.properties);
        if (tag) {
            try {
                this.messageListen.addMessageLister(this.queue, this.messageHandler(), this.isAck);
                return Boolean.TRUE;
            } catch (Exception e) {
                if (this.logger.isDebugEnabled()) {
                    e.printStackTrace();
                }
                return Boolean.FALSE;
            }

        }
        return tag;
    }

}

